package com.zy.crypto;


import javax.crypto.Cipher;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA加密工具类
 */
public class RSACoding {
	public static final String KEY_ALGORITHM = "RSA";

	private final byte[] KEY_BYTES;
	private final boolean privateKey;

	public RSACoding(byte[] keyBytes, boolean privateKey) {
		this.KEY_BYTES = keyBytes;
		this.privateKey = privateKey;
	}

	/**
	 * 解密<br>
	 * 用公钥解密
	 */
	public byte[] decode(byte[] data) {
		try {
			return process(data, Cipher.DECRYPT_MODE);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 加密<br>
	 * 用公钥加密
	 */
	public byte[] encode(byte[] data) {
		try {
			return process(data, Cipher.ENCRYPT_MODE);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private byte[] process(byte[] data, int type) throws Exception {
		byte[] keyBytes = KEY_BYTES;

		// 生成密钥
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		KeySpec spec = null;
		Key key = null;
		if (privateKey) {// 获得私钥
			spec = new PKCS8EncodedKeySpec(keyBytes);
			key = keyFactory.generatePrivate(spec);
		} else {// 取得公钥
			spec = new X509EncodedKeySpec(keyBytes);
			key = keyFactory.generatePublic(spec);
		}

		// 加密或者解密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(type, key);

		return cipher.doFinal(data);
	}

	public static void main(String[] args) throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
		keyPairGen.initialize(512);
		KeyPair keyPair = keyPairGen.generateKeyPair();

		RSACoding publicRSACoding = new RSACoding(keyPair.getPublic().getEncoded(), false);
		RSACoding privateRSACoding = new RSACoding(keyPair.getPrivate().getEncoded(), true);



		long start = System.currentTimeMillis();
		byte[] bs = publicRSACoding.encode("hello".getBytes());
		System.out.println(bs.length);
		System.out.println(new String(privateRSACoding.decode(bs)));

		bs = privateRSACoding.encode("hello2".getBytes());
		System.out.println(bs.length);
		System.out.println(new String(publicRSACoding.decode(bs)));

		bs = privateRSACoding.encode("hello3".getBytes());
		System.out.println(bs.length);
		System.out.println(new String(publicRSACoding.decode(bs)));

		System.out.println(System.currentTimeMillis() - start);
	}
}
